class EditMode {
  static singleton = {}

  constructor (vueComponent) {
    this.vueComponent = vueComponent
    this.rootElement = vueComponent.$el
    this.listenersFuncCache = {}
    EditMode.singleton = this

    this.cssRules = {}
    this.setCssStyleBackup = []

    let styleSheets = document.styleSheets
    this.defaultStyleSheet = styleSheets[styleSheets.length - 1]
    this.addCssStyleBackup = []
  }

  // 对事件监听器进一步封装,可以更快的对监听器进行修改,而不用遍历dom
  listenersRegister (funcName) {
    if (!this.listenersFuncCache[funcName]) {
      this.listenersFuncCache[funcName] = e => {
        if (EditMode.singleton[funcName]) {
          EditMode.singleton[funcName](e)
        }
      }
    }
    return this.listenersFuncCache[funcName]
  }

  rollbackSetCssStyles () {
    for (let i = 0; i < this.setCssStyleBackup.length; i++) {
      let params = this.setCssStyleBackup[i].split('|')
      this.setCssStyle(params[0], params[1], params[2])
    }
  }

  setCssStyle (className, property, value) {
    if (this.cssRules[className] && this.cssRules[className].style[property]) {
      this.cssRules[className].style[property] = value
      return
    }
    let styleSheets = document.styleSheets
    for (let i = styleSheets.length - 1; i >= 0; i--) {
      let cssRules = styleSheets[i].cssRules
      for (let j = 0; j < cssRules.length; j++) {
        let selectors = cssRules[j].selectorText.split(', ')
        if (selectors.includes('.' + className)) {
          this.setCssStyleBackup.push(
            className + '|' + property + '|' + cssRules[j].style[property]
          )
          this.cssRules[className] = cssRules[j]
          this.cssRules[className].style[property] = value
          return
        }
      }
    }
  }

  rollbackAddCssStyles () {
    let selectorText = null
    let cssRules = this.defaultStyleSheet.cssRules
    let startIdx = cssRules.length - 1
    while ((selectorText = this.addCssStyleBackup.pop())) {
      for (let i = startIdx; i >= 0; i--) {
        startIdx--
        if (selectorText === cssRules[i].selectorText) {
          this.defaultStyleSheet.deleteRule(i)
          break
        }
      }
    }
  }

  addCssStyle (selectorText, contentText) {
    let idx = this.defaultStyleSheet.insertRule(
      selectorText + contentText,
      this.defaultStyleSheet.cssRules.length
    )
    this.addCssStyleBackup.push(
      this.defaultStyleSheet.cssRules[idx].selectorText
    )
  }

  static traverseSiblingElements (from, to, func) {
    if (!from || !to) {
      return false
    }
    let el = from
    if (
      from.ariaPosInSet &&
      to.ariaPosInSet &&
      from.ariaPosInSet - to.ariaPosInSet > 0
    ) {
      el = to
      to = from
      from = el
    }
    while (el) {
      let next = el.nextElementSibling
      if (!func || !func(el)) {
        return false
      }
      if (el === to) {
        return true
      }
      el = next
    }
    return true
  }

  listenersDispenser (from, to) {}

  initCssStyles () {}

  onCreate () {
    this.initCssStyles()
    this.listenersDispenser()
  }

  onStart () {}

  onDestroy () {
    this.rollbackSetCssStyles()
    this.rollbackAddCssStyles()
    EditMode.singleton = {}
  }
}

export { EditMode }
